package LocalMinMax;

import java.util.Scanner;
import java.util.Random;

/**
 * Exercise 3.4
 * @author Katrin Baryshnikova
 */
public class LocalMinMax {
    // Точка входа
    /**
     * 
     * @param args
     */
    public static void main(String[] args) {
        int n;
        Random rn = new Random();
        Scanner in = new Scanner(System.in);
        System.out.println("Enter the number of columns & rows of matrix : ");
        n = in.nextInt();
        // Создание произвольной матрицы
        Integer[][] matrix = new Integer[n][n];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                matrix[i][j] = rn.nextInt(1000);
                System.out.print(matrix[i][j] + " ");
            }
            System.out.println();
        }
        // Ответ
        Integer[][] answer = findLocalMinMax(matrix);
        System.out.println("Local Minumum :");
        for (int j = 0; j < answer[0].length; j++) {
            if (answer[0][j] != null) {
                System.out.print(answer[0][j] + " ");
            }
        }
        System.out.println();
        System.out.println("Local Maximum :");
        for (int j = 0; j < answer[1].length; j++) {
            if (answer[1][j] != null) {
                System.out.print(answer[1][j] + " ");
            }
        }
    }

    /**
     * Функция формитует из исходной матрицы новую содежржащую список локальных
     * минимумов в первой строке и список локалных максимумов во второй
     * @param x исходная матрица 
     * @return  - двухмерная матрица  
     */
    public static Integer[][] findLocalMinMax(Integer[][] x) {
        Integer[][] localMinMax = new Integer[2][x.length];
        int countI = 0, countJ = 0;
        for (int i = 0; i < x.length; i++) {
            int count = 0, numOfSmall = 0, numOfBiger = 0;
            for (int j = 0; j < x[1].length; j++) {
                // По очереди проверяем все граничные с (i, j) 
                // клетки по восьми напрвлениям и подсчитываем количество 
                // элементов больших или меньших текущей позиции
                if (i - 1 >= 0 && j - 1 >= 0) {
                    if (x[i - 1][j - 1] > x[i][j]) {
                        numOfBiger++;
                    } else if (x[i - 1][j - 1] < x[i][j]) {
                        numOfSmall++;
                    }
                    count++;
                }
                if (i - 1 >= 0) {
                    if (x[i - 1][j] > x[i][j]) {
                        numOfBiger++;
                    } else if (x[i - 1][j] < x[i][j]) {
                        numOfSmall++;
                    }
                    count++;
                }
                if (i - 1 >= 0 && j + 1 < x[i].length) {
                    if (x[i - 1][j + 1] > x[i][j]) {
                        numOfBiger++;
                    } else if (x[i - 1][j + 1] < x[i][j]) {
                        numOfSmall++;
                    }
                    count++;
                }
                if (j - 1 >= 0) {
                    if (x[i][j - 1] > x[i][j]) {
                        numOfBiger++;
                    } else if (x[i][j - 1] < x[i][j]) {
                        numOfSmall++;
                    }
                    count++;
                }
                if (j + 1 < x[i].length) {
                    if (x[i][j + 1] > x[i][j]) {
                        numOfBiger++;
                    } else if (x[i][j + 1] < x[i][j]) {
                        numOfSmall++;
                    }
                    count++;
                }
                if (i + 1 < x.length && j - 1 >= 0) {
                    if (x[i + 1][j - 1] > x[i][j]) {
                        numOfBiger++;
                    } else if (x[i + 1][j - 1] < x[i][j]) {
                        numOfSmall++;
                    }
                    count++;
                }
                if (i + 1 < x.length) {
                    if (x[i + 1][j] > x[i][j]) {
                        numOfBiger++;
                    } else if (x[i + 1][j] < x[i][j]) {
                        numOfSmall++;
                    }
                    count++;
                }
                if (i + 1 < x.length && j + 1 < x[i].length) {
                    if (x[i + 1][j + 1] > x[i][j]) {
                        numOfBiger++;
                    } else if (x[i + 1][j + 1] < x[i][j]) {
                        numOfSmall++;
                    }
                    count++;
                }
                // Если общее количество соседей матрицы совпадает с количеством 
                // соседей больших ее, то добавляем в первую строку ответа
                if (count == numOfBiger) {
                    localMinMax[0][countI++] = x[i][j];
                }
                // Если общее количество соседей матрицы совпадает с количеством 
                // соседей меньше ее, то добавляем во вторую строку ответа
                if (count == numOfSmall) {
                    localMinMax[1][countJ++] = x[i][j];
                }
            }
        }
        return localMinMax;
    }
}
